package com.fatgirl.net.socket
{
	
	import com.fatgirl.net.IMessage;
	
	import flash.utils.ByteArray;
	import flash.utils.Endian;

	
	/**
	 *  
	 * 多协议socket封装
	 * 协议头长度 目前默认为2个字节
	 * 使用此类必须 继承 覆盖readLength 和 writeLength 方法
	 * @author iceman
	 * 
	 */
	public class FSocket extends AbsSocket
	{
		/**
		 * 用几个字节记录数据的长度（默认2个字节） 
		 */
		protected var DATA_LENGHT:int = 2;
		private var m_buffer:ByteArray;//缓冲池
		private var m_DataLen:int;//当前数据长度
		public function FSocket()
		{
			super();
			m_buffer = new ByteArray;
			m_buffer.endian = this.endian;
		}
		protected override function read(_byteArr:ByteArray):void
		{
			_byteArr.readBytes(m_buffer,m_buffer.length,_byteArr.length);
			reading();
		}
		/**
		 * 读取数据中 
		 * 
		 */
		private function reading():void
		{
			var t_nowBufferLen:int = m_buffer.length;
			if(t_nowBufferLen<DATA_LENGHT)
			{
				return;//继续等待数据
			}
			m_buffer.position = 0;	
			m_DataLen = readLength(m_buffer);
			//ftrace(this,"收到协议长："+m_DataLen,"当前长度:"+t_nowBufferLen);
			if(t_nowBufferLen>=m_DataLen)
			{
				var t_bytes:ByteArray = new ByteArray;
				t_bytes.endian = this.endian;
				m_buffer.readBytes(t_bytes,0,m_DataLen-DATA_LENGHT);
				//协议分析
				this.getProtocol().read(t_bytes);
				if(t_nowBufferLen>m_DataLen)
				{
					var t_spilthBytes:ByteArray = new ByteArray;
					t_spilthBytes.endian = this.endian;
					m_buffer.readBytes(t_spilthBytes,0,t_nowBufferLen - m_DataLen);
					m_buffer = new ByteArray;
					m_buffer.endian = this.endian;
					t_spilthBytes.readBytes(m_buffer,0,t_spilthBytes.length);
					reading();
				}
				else
				{
					m_buffer = new ByteArray;//置空缓冲池
					m_buffer.endian = this.endian;
				}
			}
			
		}
		
		/**
		 * 发出数据 
		 * 在这里进行加密 压缩处理
		 * @param _cmd
		 * 
		 */
		public override function call(_IMessage:IMessage):void
		{
			if(!_IMessage)
			{
				throw new FatError(FatError.VALUE_IS_NULL);
			}
			var t_bytes:ByteArray = new ByteArray;
			t_bytes.endian = this.endian;
			this.getProtocol().write(t_bytes,_IMessage);
			var t_SendBytes:ByteArray  = new ByteArray;
			t_SendBytes.endian = this.endian;
			var t_len:int = t_bytes.length;
			writeLength(t_SendBytes,t_len+DATA_LENGHT);
			t_SendBytes.writeBytes(t_bytes,0,t_len);
			ftrace(this,"发送协议ID="+_IMessage.id,"实际长度："+t_SendBytes.length,"填写长度："+(t_len+DATA_LENGHT));
			this.send(t_SendBytes);
		}
		protected function readLength(_bytes:ByteArray):int
		{
			throw new Error("必须重写此函数！");
		}
		protected function writeLength(_bytes:ByteArray,_len:int):void
		{
			throw new Error("必须重写此函数！");
		}
		
		
	}
}